﻿namespace DataAccessTest
{
    using System;
    using System.Collections.Generic;

    using DataAccess;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// OrienteeringMapsDataAccessTest contains unit tests for OrienteeringMapsDataAccess
    /// </summary>
    [TestClass]
    public class OrienteeringMapsDataAccessTest
    {
        private static readonly OrienteeringMapsDataAccess OrienteeringMapsDataAccess = new OrienteeringMapsDataAccess();

        // Scales for testing
        private static MapScale scale4000;
        private static MapScale scale5000;
        private static MapScale scale10000;
        private static MapScale scale15000;

        // Clubs for testing
        // ReSharper disable InconsistentNaming
        private static Club clubBussolaOK; // ReSharper restore InconsistentNaming
        private static Club clubThurgorienta;

        // Points of Sale for testing
        private static PointOfSale posVogelsang;
        private static PointOfSale posWegmüller;

        // Maps for testing
        private static Map mapGisliflue;
        private static Map mapHörnliwald;

        #region Additional test attributes

        // Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize]
        public static void MyClassInitialize(TestContext testContext)
        {
        }

        // Use ClassCleanup to run code after all tests in a class have run
        [ClassCleanup]
        public static void MyClassCleanup()
        {
            OrienteeringMapsDataAccess.DeleteAllMaps();
        }

        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }

        // Use TestCleanup to run code after each test has run
        [TestCleanup]
        public void MyTestCleanup()
        {
            OrienteeringMapsDataAccess.DeleteAllMaps();
            OrienteeringMapsDataAccess.DeleteAllScales();
            OrienteeringMapsDataAccess.DeleteAllClubs();
            OrienteeringMapsDataAccess.DeleteAllPointsOfSale();
        }
        #endregion
        
        [TestMethod]
        public void TestAddMap()
        {
            CreateMapTestEnvironment();

            CreateGisliflue();
            OrienteeringMapsDataAccess.AddMap(mapGisliflue);

            List<Map> maps = OrienteeringMapsDataAccess.GetMaps();
            Assert.AreEqual(1, maps.Count);

            CreateHörnliwald();
            OrienteeringMapsDataAccess.AddMap(mapHörnliwald);

            maps = OrienteeringMapsDataAccess.GetMaps();
            Assert.AreEqual(2, maps.Count);
        }

        [TestMethod]
        public void TestDeleteMap()
        {
            CreateMapTestEnvironment();

            CreateGisliflue();
            OrienteeringMapsDataAccess.AddMap(mapGisliflue);

            List<Map> maps = OrienteeringMapsDataAccess.GetMaps();
            Assert.AreEqual(1, maps.Count);

            OrienteeringMapsDataAccess.DeleteMap(mapGisliflue);

            maps = OrienteeringMapsDataAccess.GetMaps();
            Assert.AreEqual(0, maps.Count);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestDeleteMapNull()
        {
            CreateGisliflue();
            OrienteeringMapsDataAccess.AddMap(mapGisliflue);

            List<Map> maps = OrienteeringMapsDataAccess.GetMaps();
            Assert.AreEqual(1, maps.Count);

            OrienteeringMapsDataAccess.DeleteMap(null);
        }

        [TestMethod]
        public void TestPointOfSaleCreation()
        {
            CreatePointsOfSale();
            Assert.AreEqual(2, OrienteeringMapsDataAccess.GetPointsOfSale().Count);
        }

        [TestMethod]
        public void TestClubCreation()
        {
            CreateClubs();
            Assert.AreEqual(2, OrienteeringMapsDataAccess.GetClubs().Count);
        }

        #region Test ClassInitialize helper methods
        private static void CreateScales()
        {
            scale4000 = new MapScale { Scale = 4000, ScaleText = "1:4'000", ID = Guid.NewGuid() };
            scale5000 = new MapScale { Scale = 5000, ScaleText = "1:5'000", ID = Guid.NewGuid() };
            scale10000 = new MapScale { Scale = 10000, ScaleText = "1:10'000", ID = Guid.NewGuid() };
            scale15000 = new MapScale { Scale = 15000, ScaleText = "1:15'000", ID = Guid.NewGuid() };

            OrienteeringMapsDataAccess.AddScale(scale4000);
            OrienteeringMapsDataAccess.AddScale(scale5000);
            OrienteeringMapsDataAccess.AddScale(scale10000);
            OrienteeringMapsDataAccess.AddScale(scale15000);
        }

        private static void CreateClubs()
        {
            clubBussolaOK = new Club { Name = "Bussola OK", ID = Guid.NewGuid() };
            clubThurgorienta = new Club { Name = "Thurgorienta", ID = Guid.NewGuid() };

            OrienteeringMapsDataAccess.AddClub(clubBussolaOK);
            OrienteeringMapsDataAccess.AddClub(clubThurgorienta);
        }

        private static void CreatePointsOfSale()
        {
            posVogelsang = new PointOfSale
            {
                Adress = "Plattenstrasse 26",
                City = "Dottikon",
                Contact = "Peter Vogelsang",
                Country = "Switzerland",
                EMail = "voegi53@bluemail.ch",
                ID = Guid.NewGuid(),
                PLZ = 5605
            };

            posWegmüller = new PointOfSale
            {
                Adress = "Hauptstrasse 26",
                City = "Buch bei Frauenfeld",
                Contact = "Urs Wegmüller",
                Country = "Switzerland",
                Telephone = "052 746 13 57",
                ID = Guid.NewGuid(),
                PLZ = 8524
            };

            OrienteeringMapsDataAccess.AddPointOfSale(posVogelsang);
            OrienteeringMapsDataAccess.AddPointOfSale(posWegmüller);
        }

        private static void CreateGisliflue()
        {
            mapGisliflue = new Map { Name = "Gisliflue", Number = "1488", ReleaseYear = 2008, Club = clubBussolaOK, Scale = scale10000, PointOfSale = posVogelsang, ID = Guid.NewGuid() };
        }

        private static void CreateHörnliwald()
        {
            mapHörnliwald = new Map { Name = "Hörnliwald", Number = "1129", ReleaseYear = 2008, Club = clubThurgorienta, Scale = scale10000, PointOfSale = posWegmüller, ID = Guid.NewGuid() };
        }

        private static void CreateMapTestEnvironment()
        {
            CreateScales();
            CreateClubs();
            CreatePointsOfSale();
        }
        #endregion
    }
}
